#include <stx/safe_std_library/safe_stdlib.h>

/*
    ISO/IEC 9899:1999 7.20.6.1 The abs, labs and llabs functions
    The abs, labs, and llabs functions compute the absolute value of an integer j.
    If the result cannot be represented, the behavior is undeﬁned. The absolute
    value of the most negative number cannot be represented in two’s complement.
    E.g.: abs(INT_MIN), labs(LONG_MIN), llabs(LLONG_MIN) - cause undefined
    behavior.
*/
unsigned int abs_s(int n)
{
    unsigned int ret;
    if (n > 0) {
        ret = n;
    } else {
        ret = -n;
    }
    return ret;
}

unsigned long labs_s(long n)
{
    unsigned long ret;
    if (n > 0) {
        ret = n;
    } else {
        ret = -n;
    }
    return ret;
}

#if STX_HAS_LONG_LONG
unsigned long long llabs_s(long long n)
{
    unsigned long long ret;
    if (n > 0) {
        ret = n;
    } else {
        ret = -n;
    }
    return ret;
}
#endif

/*
    ISO/IEC 9899:1999 7.20.4.2 The atexit function
    It is not specified, whether function should return error if NULL is passed
    as argument.  
*/
int atexit_s(void (*func)(void))
{
    int ret = 1;
    if (func) {
        ret = atexit(func);
    }
    return ret;
}

void* calloc_s(size_t num, size_t size)
{
    void* ret = NULL;
    if ((num <= (~((size_t) 0))/size) && num && size) {
        ret = calloc(num, size);
    }
    return ret;
}

void* malloc_s(size_t size)
{
    void* ret = NULL;
    if (size) {
        ret = malloc(size);
    }
    return ret;
}

void* realloc_s(void* ptr, size_t size)
{
    void* ret = NULL;
    if (ptr) {
        if (size) {
            ret = realloc(ptr, size);
        } else {
            free(ptr);
        }
    } else if (size) {
        ret = malloc(size);
    }
    return ret;
}

void free_s(void* ptr)
{
    if (ptr) {
        free(ptr);
    }
}
